﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Security.Cryptography;
using System.Text;
using equinoxWeb.Models;
using equinoxWeb.GestionConexion;
using MySql.Data.MySqlClient;
namespace equinoxWeb.Controllers
{
    public class CuentaController : Controller
    {
        private static string secret = "n?1YAhXvk?5vo;s";

        public ActionResult Ingresar()
        {
            ViewBag.sesion = false;
            return View();
        }

        [HttpPost]
        public ActionResult Ingresar(Usuario model, string returnUrl, string recuerdame)
        {
            if (model.Contrasenha == null)
            {
                model.Contrasenha = "";
            }
            Usuario user;
            try
            {
                user = CuentaFunction.loginCorrecto(model);
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);
                return View("~/Views/Shared/Error.cshtml");
            }
            if (user == null)
            {
                ModelState.AddModelError("Cuenta", "El Usuario o Contraseña son Incorrectos");
                return View(model);
            }
            string hPass = hashPassword(model.Contrasenha + user.Salt);
            model.Contrasenha = hPass;
            if (model.Contrasenha == user.Contrasenha)
            {
                string nombre = CuentaFunction.getNombreByUsername(model.Cuenta);
                HttpCookie myCookie = new HttpCookie("username", model.Cuenta + "|" + hashPassword(model.Cuenta + secret) + "|" + nombre);
                if (recuerdame == "true")
                {
                    myCookie.Expires = DateTime.Now.AddYears(1);//la cookie tendra validez de 1 año
                }
                else
                {
                    myCookie.Expires = DateTime.MinValue;
                }
                HttpContext.Response.Cookies.Add(myCookie);
                HttpCookie langCookie = new HttpCookie("idioma","ES");
                langCookie.Expires = DateTime.Now.AddYears(1);//la cookie tendra validez de 1 año
                HttpContext.Response.Cookies.Add(myCookie);
                ViewBag.mensaje = "Se inició sesión con éxito";
                ViewBag.returnURL = returnUrl;
                if (returnUrl == null)
                    return RedirectToAction("MisCasos", "Caso");
                return Redirect(returnUrl);
            }
            ModelState.AddModelError("Cuenta", "El Usuario o Contraseña son Incorrectos");
            return View(model);
        }

        public static void setIdioma(HttpContextBase contexto,string idioma)
        {
            HttpCookie idiomaCookie = new HttpCookie("idioma", idioma);// se setea la cookie a vacia asi ya se considera que no existe
            contexto.Response.Cookies.Add(idiomaCookie);
        }

        public static string getIdioma(HttpContextBase contexto)
        {
            HttpCookie idiomaCookie = contexto.Request.Cookies["idioma"];
            if (idiomaCookie == null) return "EN";
            return idiomaCookie.Value;
        }

        private static string hashPassword(string password)
        {
            SHA256 hasher = SHA256.Create();
            byte[] passBytes = Encoding.UTF8.GetBytes(password + CuentaController.secret);
            byte[] hashBytes = hasher.ComputeHash(passBytes);
            return Convert.ToBase64String(hashBytes);
        }

        public static bool validarLogueo(HttpContextBase contexto)
        {
            HttpCookie myCookie;
            myCookie = contexto.Request.Cookies["username"];
            if (myCookie == null) return false;
            string[] userAndPass = myCookie.Value.Split('|');

            if (userAndPass.Length == 3)
            {
                if (hashPassword(userAndPass[0] + secret) == userAndPass[1]) return true;
            }
            return false;
        }

        public ActionResult Registrarse()
        {
            return View();
        }

        private static string RandomString(int size)
        {
            StringBuilder builder = new StringBuilder();
            Random random = new Random();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }
            return builder.ToString();
        }

        public static Usuario getUsuario(HttpContextBase contexto)
        {
            HttpCookie myCookie;
            myCookie = contexto.Request.Cookies["username"];
            if (myCookie == null) return null;
            string[] userAndPass = myCookie.Value.Split('|');
            if (userAndPass.Length == 3)
            {
                if (hashPassword(userAndPass[0] + secret) == userAndPass[1])
                {
                    Usuario user;
                    try
                    {
                        user = CuentaFunction.getUsuarioByUsername(userAndPass[0]);
                    }
                    catch (Exception ex)
                    {
                        System.Console.WriteLine(ex.Message);
                        return null;
                    }
                    if (user != null) return user;
                }
            }
            return null;
        }

        public static string getNombre(HttpContextBase contexto)
        {
            HttpCookie myCookie;
            myCookie = contexto.Request.Cookies["username"];
            if (myCookie == null) return null;
            string[] userAndPass = myCookie.Value.Split('|');

            if (userAndPass.Length == 3)
            {
                return userAndPass[2];
            }
            return null;
        }

        public static bool registrarCliente(int idcliente,string cuenta,MySqlConnection con)
        {
            bool existe;
            Usuario usuario = new Usuario();
            usuario.Cuenta = cuenta;
            usuario.Contrasenha = cuenta;
            existe = CuentaFunction.existeUsuario(usuario.Cuenta);
            if (!existe)
            {
                string salt = CuentaController.RandomString(30);
                usuario.Salt = salt;
                usuario.Contrasenha = hashPassword(usuario.Contrasenha + salt);
                usuario.IdUsuario = CuentaFunction.getNextId();
                
                CuentaFunction.insertarUsuario(usuario,con);
                return true;

            }
            else
                return false;
        }

        [HttpPost]
        public ActionResult Registrarse(Usuario usuario, string confirmacion)
        {
            if (confirmacion != usuario.Contrasenha) ModelState.AddModelError("Contrasenha", "Ambas contraseñas deben coincidir");
            bool existe;
            try
            {
                existe = CuentaFunction.existeUsuario(usuario.Cuenta);
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);
                return View("~/Views/Shared/Error.cshtml");
            }
            if (existe)
            {
                ModelState.AddModelError("Cuenta", "Ya existe ese usuario");
            }
            if (ModelState.IsValid)
            {
                try
                {
                    string salt = CuentaController.RandomString(30);
                    usuario.Salt = salt;
                    usuario.Contrasenha = hashPassword(usuario.Contrasenha + salt);
                    usuario.IdUsuario = CuentaFunction.getNextId();
                    CuentaFunction.insertarUsuario(usuario);
                }
                catch (Exception ex)
                {
                    System.Console.WriteLine(ex.Message);
                    return View("~/Views/Shared/Error.cshtml");
                }
                return RedirectToAction("Index", "Home");
            }
            return View(usuario);
        }

        public ActionResult CambiarPassword()
        {
            if (!CuentaController.validarLogueo(HttpContext))
            {
                return RedirectToAction("Index", "Home", new { returnUrl = HttpContext.Request.Path });
            }
            Usuario user = CuentaController.getUsuario(this.HttpContext);
            ViewBag.esCliente = !(user.IdCliente == 0);
            ViewBag.idClienteLogueado = user.IdCliente;
            ViewBag.enSesion = true;
            ViewBag.lang = CuentaController.getIdioma(this.HttpContext);
            ViewBag.nombreUsuario = CuentaController.getNombre(this.HttpContext);
            return View();
        }

        //
        // POST: /Account/ChangePassword

        [HttpPost]
        public ActionResult CambiarPassword(string actual, string nuevo, string conf)
        {
            if (!CuentaController.validarLogueo(HttpContext))
            {
                return RedirectToAction("Index", "Home", new { returnUrl = HttpContext.Request.Path });
            }
            if (nuevo == conf)
            {
                Usuario user;
                try
                {
                    user = CuentaController.getUsuario(HttpContext);
                }
                catch (Exception ex)
                {
                    return View("~/Views/Shared/Error.cshtml");
                }
                if (user.Contrasenha != hashPassword(actual + user.Salt))
                {
                    ViewBag.error = "La contraseña no es la actual";
                    return View();
                }
                user.Contrasenha = hashPassword(nuevo + user.Salt);
                try
                {
                    CuentaFunction.cambiarPassword(user);
                }
                catch (Exception ex)
                {
                    return View("~/Views/Shared/Error.cshtml");
                }

                return RedirectToAction("Index", "Home");
            }
            ViewBag.error = "La nueva contraseña no coincide con su confirmación";
            // Si llegamos a este punto, es que se ha producido un error y volvemos a mostrar el formulario
            return View();
        }


        public ActionResult CambiarIdioma()
        {
            string idioma = CuentaController.getIdioma(this.HttpContext);
            if (idioma == "ES")
                CuentaController.setIdioma(this.HttpContext, "EN");
            else
                CuentaController.setIdioma(this.HttpContext, "ES");
            return RedirectToAction("Index", "Home");
        }
        public ActionResult LogOff()
        {

            HttpCookie blankCookieUser = new HttpCookie("username", "");// se setea la cookie a vacia asi ya se considera que no existe
            HttpContext.Response.Cookies.Add(blankCookieUser);
            return RedirectToAction("Index", "Home");
        }
    }
}
